package city.spring.modules.system.service;

import city.spring.modules.system.dto.MenuViewDTO;
import city.spring.modules.system.entity.MenuEntity;
import city.spring.modules.system.entity.UserEntity;
import com.baomidou.mybatisplus.extension.service.IService;

import java.util.List;

/**
 * Service：菜单信息
 *
 * @author 侯坤林
 * @date 2020-04-12 15:33:27
 */
public interface MenuService extends IService<MenuEntity> {
    String CACHE_NAME = "menu";

    /**
     * 通过主键ID获取一个菜单信息
     *
     * @param primaryKey      菜单主键ID
     * @param loadPermissions 是否加载用户组的特殊权限列表
     * @param loadRoles       是否加载用户组的角色列表
     * @return 用户组信息 group info
     */
    MenuEntity getMenuInfo(String primaryKey, boolean loadPermissions, boolean loadRoles);

    /**
     * 加载权限信息
     *
     * @param entity 菜单
     */
    void loadPermissions(MenuEntity entity);

    /**
     * 加载权限信息
     *
     * @param entities 菜单列表
     */
    default void loadPermissions(List<MenuEntity> entities) {
        entities.forEach(this::loadPermissions);
    }

    /**
     * 加载角色信息
     *
     * @param entity 菜单
     */
    void loadRoles(MenuEntity entity);

    /**
     * 加载角色信息
     *
     * @param entities 菜单列表
     */
    default void loadRoles(List<MenuEntity> entities) {
        entities.forEach(this::loadRoles);
    }

    /**
     * 业务处理：保存一个 <strong>菜单信息</strong>
     *
     * @param entity 菜单信息
     */
    void saveMenu(MenuEntity entity);

    /**
     * 业务处理：修改一个 <strong>菜单信息</strong>
     *
     * @param entity 菜单信息
     */
    void updateMenu(MenuEntity entity);

    /**
     * 业务处理：删除一个 <strong>菜单信息</strong>
     *
     * @param primaryKey 主键ID
     */
    void deleteMenu(String primaryKey);

    /**
     * 业务处理：删除多个 <strong>菜单信息</strong>
     *
     * @param primaryKeys 主键ID列表
     */
    void deleteMenu(List<String> primaryKeys);

    /**
     * 业务处理：维护一个 <strong>多级分类信息</strong> 的父级和排序
     *
     * @param entities 多级分类信息列表
     */
    void maintainParentAndSorted(List<MenuEntity> entities);

    /**
     * 把原始数据列表转换成树形结构数据
     *
     * @param rawDatasource 原始数据列表
     * @return 从原始数据列表中转换成树形结构数据
     */
    default List<MenuEntity> converterToTreeDatasource(List<? extends MenuEntity> rawDatasource) {
        return converterToTreeDatasource(rawDatasource, true);
    }

    /**
     * 把原始数据列表转换成树形结构数据
     *
     * @param rawDatasource    原始数据列表
     * @param loadParentEntity 是否加载父级信息：如果处理后的顶级结果中依旧存在父级标识，是否继续加载结果列表中父级信息，建议传入 true ，在搜索的时候有时候只能搜索出子节点，此时可以加载出父节点西悉尼
     * @return 从原始数据列表中转换成树形结构数据
     */
    List<MenuEntity> converterToTreeDatasource(List<? extends MenuEntity> rawDatasource, boolean loadParentEntity);

    /**
     * 获取全部菜单视图（含权限信息，一个菜单会有两条记录，需要去重）。
     * <p>
     * 先查询出菜单跟权限的关联结果，然后再查询出菜单跟角色的关联结果，把两个结果合并（因此每个菜单会至少重复一次，菜单重复两次以上表明有权限信息）
     * </p>
     *
     * @return 有权限信息的菜单列表
     */
    List<MenuViewDTO> getAllMenuView();

    /**
     * 从所有菜单视图列表中过滤出用户菜单列表
     *
     * @param user  当前用户信息
     * @param menus 所有菜单视图列表
     * @return 新的属于当前用户权限范围内的菜单列表信息
     */
    List<MenuViewDTO> filterUserMenuList(UserEntity user, List<MenuViewDTO> menus);

    /**
     * 设置菜单的角色列表
     *
     * @param entity 菜单对象
     */
    void setMenuRoles(MenuEntity entity);

    /**
     * 设置菜单的附加权限列表
     *
     * @param entity 菜单对象
     */
    void setMenuPermissions(MenuEntity entity);
}